<template>
  <dialog ref="dialogRef" class="bom-view-dialog" @close="onClose">
    <form method="dialog" class="dialog-body" @submit.prevent>
      <header class="dialog-header">
        <h3 class="title">
          <span class="icon">
            <svg viewBox="0 0 24 24" stroke="currentColor" fill="none">
              <path d="M4 4h9l7 7v9a0 0 0 0 1 0 0H4a0 0 0 0 1 0 0V4Z" stroke-width="1.6" />
              <path d="M13 4v7h7" stroke-width="1.6" />
              <path d="M8 15h8M8 11h2m-2 4v4m8-4v4" stroke-width="1.6" stroke-linecap="round" />
            </svg>
          </span>
          {{ titleText }}
        </h3>
        <button type="button" class="ui-close-btn" @click="close" aria-label="关闭">
          <svg class="icon-x" viewBox="0 0 24 24" fill="none">
            <line x1="18" y1="6" x2="6" y2="18" />
            <line x1="6" y1="6" x2="18" y2="18" />
          </svg>
        </button>
      </header>

      <div class="summary-bar" v-if="bomItems.length">
        <div class="chips">
          <span class="chip total">总行 {{ bomItems.length }}</span>
          <span class="chip cost" :title="`总成本: ¥ ${totalCost.toFixed(2)}`">总成本 ¥ {{ totalCost.toFixed(2) }}</span>
        </div>
        <div class="tools">
          <input class="filter-input" v-model="filterText" placeholder="筛选 编码 / 名称 / 分类" />
        </div>
      </div>

      <section class="content" v-if="effectiveItems.length">
        <div v-if="group" class="multi-group-scroll">
          <div class="group-block" v-if="grouped.production.length">
            <h4 class="g-title">物料BOM <span class="sub-cost">合计 ¥ {{ prodCost.toFixed(2) }}</span></h4>
            <div class="table-wrapper">
              <table class="entry-table fancy">
                <thead>
                  <tr>
                    <th style="width:60px">类型</th>
                    <th style="width:80px">编码</th>
                    <th style="width:140px">名称</th>
                    <th style="width:120px">物料分类</th>
                    <th style="width:60px">规格</th>
                    <th style="width:80px">费用模式</th>
                    <th style="width:100px">金额/单价(¥)</th>
                    <th style="width:80px">数量</th>
                    <th style="width:100px">行成本(¥)</th>
                    <th style="width:70px">操作</th>
                  </tr>
                </thead>
                <tbody>
                  <tr v-for="(item, idx) in grouped.production" :key="item._localId || item.id || idx">
                    <td class="type-cell">物料</td>
                    <td>{{ item.materialCode || '-' }}</td>
                    <td>{{ item.costName || item.materialName }}</td>
                    <td class="category-cell">{{ item.category || '-' }}</td>
                    <td>{{ item.spec || '-' }}</td>
                    <td class="fee-mode">{{ item.feeDetail?.mode === 'fixed' ? '固定' : '计数' }}</td>
                    <td class="fee-amount">{{ (item.feeDetail?.amount || item.unitCost || 0).toFixed(2) }}</td>
                    <td class="qty">{{ item.feeDetail?.mode==='count' ? (item.feeDetail.quantity || item.qty || 1) : (item.qty || '-') }}</td>
                    <td class="line-cost">{{ lineCost(item).toFixed(2) }}</td>
                    <td class="actions">
                      <button class="btn link" type="button" @click="openAttr(item)">属性</button>
                      <button class="btn link" type="button" @click="openFee(item)">费用</button>
                    </td>
                  </tr>
                </tbody>
              </table>
            </div>
          </div>
          <div class="group-block" v-if="grouped.packaging.length">
            <h4 class="g-title">包装BOM <span class="sub-cost">合计 ¥ {{ packCost.toFixed(2) }}</span></h4>
            <div class="table-wrapper">
              <table class="entry-table fancy">
                <thead>
                  <tr>
                    <th style="width:60px">类型</th>
                    <th style="width:80px">编码</th>
                    <th style="width:140px">名称</th>
                    <th style="width:120px">物料分类</th>
                    <th style="width:60px">规格</th>
                    <th style="width:80px">费用模式</th>
                    <th style="width:100px">金额/单价(¥)</th>
                    <th style="width:80px">数量</th>
                    <th style="width:100px">行成本(¥)</th>
                    <th style="width:70px">操作</th>
                  </tr>
                </thead>
                <tbody>
                  <tr v-for="(item, idx) in grouped.packaging" :key="item._localId || item.id || idx">
                    <td class="type-cell">包装</td>
                    <td>{{ item.materialCode || '-' }}</td>
                    <td>{{ item.costName || item.materialName }}</td>
                    <td class="category-cell">{{ item.category || '-' }}</td>
                    <td>{{ item.spec || '-' }}</td>
                    <td class="fee-mode">{{ item.feeDetail?.mode === 'fixed' ? '固定' : '计数' }}</td>
                    <td class="fee-amount">{{ (item.feeDetail?.amount || item.unitCost || 0).toFixed(2) }}</td>
                    <td class="qty">{{ item.feeDetail?.mode==='count' ? (item.feeDetail.quantity || item.qty || 1) : (item.qty || '-') }}</td>
                    <td class="line-cost">{{ lineCost(item).toFixed(2) }}</td>
                    <td class="actions">
                      <button class="btn link" type="button" @click="openAttr(item)">属性</button>
                      <button class="btn link" type="button" @click="openFee(item)">费用</button>
                    </td>
                  </tr>
                </tbody>
              </table>
            </div>
          </div>
        </div>
        <div v-else class="table-wrapper single">
          <table class="entry-table fancy">
            <thead>
              <tr>
                <th style="width:60px">类型</th>
                <th style="width:80px">编码</th>
                <th style="width:140px">名称</th>
                <th style="width:120px">物料分类</th>
                <th style="width:60px">规格</th>
                <th style="width:80px">费用模式</th>
                <th style="width:100px">金额/单价(¥)</th>
                <th style="width:80px">数量</th>
                <th style="width:100px">行成本(¥)</th>
                <th style="width:70px">操作</th>
              </tr>
            </thead>
            <tbody>
              <tr v-for="(item, idx) in effectiveItems" :key="item._localId || item.id || idx">
                <td class="type-cell">{{ item.type==='packaging' ? '包装' : '物料' }}</td>
                <td>{{ item.materialCode || '-' }}</td>
                <td>{{ item.costName || item.materialName }}</td>
                <td class="category-cell">{{ item.category || '-' }}</td>
                <td>{{ item.spec || '-' }}</td>
                <td class="fee-mode">{{ item.feeDetail?.mode === 'fixed' ? '固定' : '计数' }}</td>
                <td class="fee-amount">{{ (item.feeDetail?.amount || item.unitCost || 0).toFixed(2) }}</td>
                <td class="qty">{{ item.feeDetail?.mode==='count' ? (item.feeDetail.quantity || item.qty || 1) : (item.qty || '-') }}</td>
                <td class="line-cost">{{ lineCost(item).toFixed(2) }}</td>
                <td class="actions">
                  <button class="btn link" type="button" @click="openAttr(item)">属性</button>
                  <button class="btn link" type="button" @click="openFee(item)">费用</button>
                </td>
              </tr>
            </tbody>
          </table>
        </div>
      </section>
      <section v-else class="content empty">暂无 BOM 数据</section>
      <footer class="dialog-actions">
        <button class="btn primary" type="button" @click="close">关闭</button>
      </footer>
    </form>
    <AttributeViewer ref="attrDialogRef" />
    <SimpleCostModeViewer ref="feeViewerRef" />
  </dialog>
</template>

<script setup lang="ts">
import { ref, computed } from 'vue';
import AttributeViewer from './AttributeViewer.vue';
import SimpleCostModeViewer from './SimpleCostModeViewer.vue';

interface BomItem {
  id?: string; _localId?: string; seq?: number; type: 'production' | 'packaging';
  materialCode?: string; materialName?: string; costName?: string; category?: string; spec?: string;
  qty?: number; unit?: string; lossFactor?: number; unitCost?: number;
  attributes?: Record<string, any>; attributeDefinitions?: any[]; attributeValues?: Record<string, any>;
  feeDetail?: { mode: 'fixed' | 'count'; amount: number; quantity?: number };
}
const dialogRef = ref<HTMLDialogElement | null>(null);
const titleText = ref('BOM 明细');
const bomItems = ref<BomItem[]>([]);
const group = ref(false);
const filterText = ref('');
const filtered = computed(() => {
  const t = filterText.value.trim().toLowerCase(); if(!t) return bomItems.value;
  return bomItems.value.filter(i => [i.materialCode, i.materialName, i.costName, i.category].some(v => v && v.toLowerCase().includes(t)));
});
const grouped = computed(() => ({
  production: filtered.value.filter(i => i.type==='production').sort((a,b)=> (a.seq||0)-(b.seq||0)),
  packaging: filtered.value.filter(i => i.type==='packaging').sort((a,b)=> (a.seq||0)-(b.seq||0))
}));
const effectiveItems = computed(() => group.value ? [...grouped.value.production, ...grouped.value.packaging] : filtered.value);
function lineCost(item: BomItem){
  if(item.feeDetail){ if(item.feeDetail.mode==='fixed') return item.feeDetail.amount||0; return (item.feeDetail.amount||0) * (item.feeDetail.quantity || item.qty || 1); }
  return (item.unitCost||0) * (item.qty||0) * (item.lossFactor||1);
}
const prodCost = computed(()=> grouped.value.production.reduce((s,i)=> s+ lineCost(i),0));
const packCost = computed(()=> grouped.value.packaging.reduce((s,i)=> s+ lineCost(i),0));
const totalCost = computed(()=> group.value ? prodCost.value + packCost.value : effectiveItems.value.reduce((s,i)=> s+ lineCost(i),0));
function open(payload: { title?: string; bomItems: BomItem[]; group?: boolean }){
  titleText.value = payload.title || 'BOM 明细'; bomItems.value = (payload.bomItems||[]).map((i,idx)=> ({ seq: idx+1, ...i })); group.value = !!payload.group; filterText.value=''; dialogRef.value?.showModal(); }
function close(){ dialogRef.value?.close(); }
function onClose(){ bomItems.value=[]; filterText.value=''; }
const attrDialogRef = ref<InstanceType<typeof AttributeViewer> | null>(null);
const feeViewerRef = ref<InstanceType<typeof SimpleCostModeViewer> | null>(null);
function openAttr(item: BomItem){ const defs = item.attributeDefinitions || Object.keys(item.attributes||{}).map(code => ({ code, name: code, control:'TextBox' })); const vals = item.attributeValues || item.attributes || {}; attrDialogRef.value?.open({ id: item.id || item._localId || 'temp', attributeDefinitions: defs, attributeValues: vals }); }
function openFee(item: BomItem){ const fd = item.feeDetail; if(!fd) return; feeViewerRef.value?.open({ id: item.id || item._localId || 'temp', costMode: fd.mode, fixedAmount: fd.mode==='fixed'?fd.amount:undefined, unitPrice: fd.mode==='count'?fd.amount:undefined } as any); }
defineExpose({ open, close });
</script>

<style scoped>
.bom-view-dialog::backdrop { background: rgba(0,0,0,.4); }
.bom-view-dialog { border:none; padding:0; border-radius:16px; width:980px; max-width:98vw; box-shadow:0 12px 32px -8px rgba(0,0,0,.3); }
.dialog-body { display:flex; flex-direction:column; max-height:70dvh; background:#fff; }
.dialog-header { display:flex; justify-content:space-between; align-items:center; padding:.9rem 1.1rem; border-bottom:1px solid #e2e8f0; }
.title { margin:0; font-size:18px; font-weight:600; display:flex; align-items:center; gap:.55rem; }
.title .icon { width:22px; height:22px; color:#2563eb; background:#eff6ff; border:1px solid #bfdbfe; display:inline-flex; align-items:center; justify-content:center; border-radius:6px; box-shadow:0 0 0 1px #ffffff inset; }
.title .icon svg { width:16px; height:16px; }
.ui-close-btn { background:none; border:1px solid transparent; cursor:pointer; padding:.45rem; border-radius:12px; color:#64748b; transition:all .3s; display:flex; align-items:center; justify-content:center; }
.ui-close-btn:hover { background:linear-gradient(135deg,#fee2e2,#fecaca); color:#dc2626; transform:rotate(90deg); }
.icon-x { width:20px; height:20px; stroke:currentColor; stroke-width:2; }
.summary-bar { display:flex; justify-content:space-between; gap:1rem; align-items:center; padding:.5rem 1.1rem .4rem; border-bottom:1px solid #f1f5f9; background:linear-gradient(90deg,#f8fafc,#ffffff); flex-wrap:wrap; }
.chips { display:flex; gap:.5rem; flex-wrap:wrap; }
.chip { font-size:12px; font-weight:600; letter-spacing:.03em; padding:.35rem .65rem; border-radius:999px; background:#e2e8f0; color:#334155; display:inline-flex; align-items:center; gap:.35rem; }
.chip.total { background:#dbeafe; color:#1e40af; }
.chip.cost { background:#fae8ff; color:#86198f; }
.tools { display:flex; gap:.6rem; align-items:center; }
.filter-input { border:1px solid #cbd5e1; border-radius:10px; padding:.45rem .7rem; font-size:13px; width:220px; background:#fff; }
.filter-input:focus { outline:2px solid #3b82f6; outline-offset:1px; }
.content { padding:1rem 1.1rem; overflow:auto; display:flex; flex-direction:column; max-height:calc(70dvh - 3.5rem); }
.multi-group-scroll { display:flex; flex-direction:column; gap:1.2rem; }
.group-block { display:flex; flex-direction:column; gap:.6rem; }
.g-title { margin:.1rem 0 .2rem; font-size:15px; font-weight:700; letter-spacing:.02em; display:flex; align-items:baseline; gap:.8rem; }
.sub-cost { font-size:12px; font-weight:600; color:#2563eb; background:#eff6ff; padding:.15rem .55rem; border-radius:12px; letter-spacing:.02em; }
.table-wrapper { border:1px solid #e2e8f0; border-radius:16px; background:#fff; box-shadow:0 4px 16px -4px rgba(15,23,42,.12),0 2px 8px -2px rgba(15,23,42,.06); overflow:auto; max-height:400px; }
.table-wrapper.single { max-height:420px; }
.entry-table { width:100%; border-collapse:separate; border-spacing:0; font-size:13px; }
.entry-table thead { position:sticky; top:0; z-index:40; }
.entry-table thead th { background:linear-gradient(135deg,#f8fafc,#f1f5f9); font-weight:700; font-size:11px; letter-spacing:.05em; text-transform:uppercase; color:#475569; border-bottom:1px solid #e2e8f0; padding:.55rem .6rem; text-align:left; }
.entry-table tbody td { background:#fff; padding:.55rem .6rem; border-bottom:1px solid #f1f5f9; }
.entry-table tbody tr { transition:background .25s; }
.entry-table tbody tr:hover { background:#f8fafc; }
.type-cell { font-weight:600; color:#475569; }
.category-cell { font-weight:500; color:#6b7280; background-color:#f3f4f6; padding:.4rem .6rem; border-radius:4px; }
.fee-mode { font-weight:600; color:#2563eb; }
.fee-amount { font-weight:600; color:#059669; text-align:right; }
.qty { font-weight:600; color:#475569; text-align:center; }
.line-cost { font-weight:600; color:#1e40af; text-align:right; }
.actions { display:flex; gap:.4rem; }
.btn { cursor:pointer; border:1px solid transparent; padding:.55rem 1rem; border-radius:10px; font-size:13px; font-weight:600; transition:all .3s; }
.btn.primary { background:#3b82f6; border-color:#2563eb; color:#fff; }
.btn.primary:hover { background:#2563eb; }
.btn.link { background:#ffffff; border:1px solid #2563eb; color:#2563eb; padding:.25rem .55rem; font-size:12px; font-weight:600; border-radius:6px; }
.btn.link:hover { background:#e0edff; color:#1d4ed8; border-color:#1d4ed8; }
.empty { margin:0; color:#64748b; font-size:14px; text-align:center; padding:3rem; }
.dialog-actions { display:flex; justify-content:flex-end; gap:.6rem; padding:.7rem 1.1rem .9rem; border-top:1px solid #e2e8f0; }
</style>
